package net.towee.server.xmpp;

import java.io.FileNotFoundException;
import java.net.URL;

import javax.inject.Inject;

import net.towee.server.CoreSettings;

import org.apache.commons.configuration.CompositeConfiguration;
import org.apache.commons.configuration.ConfigurationUtils;
import org.apache.commons.configuration.SystemConfiguration;
import org.apache.vysper.mina.C2SEndpoint;
import org.apache.vysper.mina.S2SEndpoint;
import org.apache.vysper.storage.OpenStorageProviderRegistry;
import org.apache.vysper.storage.StorageProviderRegistry;
import org.apache.vysper.xmpp.authentication.AccountManagement;
import org.apache.vysper.xmpp.modules.extension.xep0092_software_version.SoftwareVersionModule;
import org.apache.vysper.xmpp.modules.extension.xep0199_xmppping.XmppPingModule;
import org.apache.vysper.xmpp.modules.extension.xep0202_entity_time.EntityTimeModule;
import org.apache.vysper.xmpp.modules.roster.persistence.RosterManager;
import org.apache.vysper.xmpp.server.ServerRuntimeContext;
import org.apache.vysper.xmpp.server.XMPPServer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.inject.Provider;
import com.google.inject.name.Named;

/**
 * Main point of XMPP server
 * 
 * @author c58
 */
public class ToweeXMPPStarter  implements Provider<ServerRuntimeContext> {
	private static final Logger LOG = LoggerFactory.getLogger(ToweeXMPPStarter.class);
	
	private final AccountManagement accountManagment;
	private final RosterManager rosterManager;
	private final String domain;
	
	@Inject
	public ToweeXMPPStarter(AccountManagement accountManager, RosterManager rosterManager,
			@Named(CoreSettings.TOWEE_SERVER_DOMAIN) String domain) {
		this.accountManagment = accountManager;
		this.rosterManager = rosterManager;
		this.domain = domain;
	}
	
	@Override
	public ServerRuntimeContext get() {
		// Get path to cert
		final CompositeConfiguration config = new CompositeConfiguration();
		config.addConfiguration(new SystemConfiguration());
		String propertyFile = config.getString("net.towee.cert");
        URL url = ConfigurationUtils.locate(null, propertyFile);
		
		// Choose the storage you want to use
    	StorageProviderRegistry providerRegistry = new OpenStorageProviderRegistry();
    	providerRegistry.add(accountManagment);
    	providerRegistry.add(rosterManager);
		
    	// Create server
		XMPPServer server = new XMPPServer( domain );
		server.addEndpoint(new C2SEndpoint());
    	server.addEndpoint(new S2SEndpoint());
		server.setStorageProviderRegistry(providerRegistry);

		// Set TLS cert
		try {
			server.setTLSCertificateInfo(ConfigurationUtils.fileFromURL(url), "vcyddbdc");
		} catch (FileNotFoundException e1) {
			LOG.error("Cert file not found!");
			throw new RuntimeException();
		}
		
		// Start the server
		try {
			server.start();
			LOG.info("XMPP server started");
		} catch (Exception e) {
		    e.printStackTrace();
		}
		
		// Enable s2s
    	server.getServerRuntimeContext().getServerFeatures().setRelayingToFederationServers(true);
    	//server.getServerRuntimeContext().getResourceRegistry().
		
		// Add modules
		server.addModule(new SoftwareVersionModule());
		server.addModule(new EntityTimeModule());
		server.addModule(new XmppPingModule());
		
		// Return server context
	    return server.getServerRuntimeContext();
	}

}
